package com.design.springboot.booksharing.controller;

import com.design.springboot.booksharing.bean.*;
import com.design.springboot.booksharing.component.ApiResultComponent;
import com.design.springboot.booksharing.constant.SystemConstant;
import com.design.springboot.booksharing.enums.ApiResultCodeEnum;
import com.design.springboot.booksharing.service.BookInfoService;
import com.design.springboot.booksharing.utils.FileUtils;
import com.design.springboot.booksharing.utils.snowflake.Snowflake;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;

/**
 * 书籍信息表(BookInfo)控制器
 *
 * @author admin
 */
@Slf4j
@RestController
@RequestMapping("/bookInfo")
public class BookInfoController {
    @Resource
    ApiResultComponent apiResultComponent;

    @Resource
    private BookInfoService bookInfoService;

    @Resource
    Snowflake snowflake;

    private String baseDir;

    public BookInfoController() {
        this.baseDir = FileUtils.getFileBaseDir();
    }

    @PostMapping("/saveBookInfo")
    public ApiResult<BookInfo> saveBookInfo(
        @SessionAttribute(name = SystemConstant.ACTIVE_USER) ActiveUser activeUser,
        BookInfo bookInfo,
        @RequestBody MultipartFile file) {
        if (file != null) {
            try {
                String extension = FilenameUtils.getExtension(file.getOriginalFilename());
                String nextId = snowflake.nextId().toString();
                // 上传并返回新文件名称
                String fileName = nextId + "." + extension;
                file.transferTo(new File(baseDir, fileName));

                bookInfo.setCoverImage(fileName);
            } catch (Exception e) {
                return apiResultComponent.error(ApiResultCodeEnum.UPLOAD_ERROR);
            }
        }

        bookInfo.setOwnerUserId(activeUser.getUserId());
        Boolean saveBookInfo = bookInfoService.saveBookInfo(bookInfo);
        if (saveBookInfo) {
            BookInfo bookInfoById = bookInfoService.getBookInfoById(bookInfo.getId());
            return apiResultComponent.success(bookInfoById);
        }
        return apiResultComponent.error(ApiResultCodeEnum.ADD_ERROR);
    }

    @PostMapping("/updateBookInfo")
    public ApiResult<BookInfo> updateBookInfo(BookInfo bookInfo, @RequestBody MultipartFile file) {
        if (file != null) {
            try {
                String extension = FilenameUtils.getExtension(file.getOriginalFilename());
                String nextId = snowflake.nextId().toString();
                // 上传并返回新文件名称
                String fileName = nextId + "." + extension;
                file.transferTo(new File(baseDir, fileName));

                String coverImage = bookInfo.getCoverImage();
                FileUtils.deleteFile(new File(baseDir, coverImage).getAbsolutePath());
                bookInfo.setCoverImage(fileName);
            } catch (Exception e) {
                return apiResultComponent.error(ApiResultCodeEnum.UPLOAD_ERROR);
            }
        }

        Boolean updateBookInfo = bookInfoService.updateBookInfo(bookInfo);
        if (updateBookInfo) {
            BookInfo bookInfoById = bookInfoService.getBookInfoById(bookInfo.getId());
            return apiResultComponent.success(bookInfoById);
        }
        return apiResultComponent.error(ApiResultCodeEnum.UPDATE_ERROR);
    }

    @PostMapping("/borrowBook")
    public ApiResult<BookInfo> borrowBook(@SessionAttribute(SystemConstant.ACTIVE_USER) ActiveUser activeUser,
        @RequestBody BookInfo bookInfo) {
        Integer id = bookInfo.getId();

        BookInfo bookInfoById = bookInfoService.getBookInfoById(id);
        if (bookInfoById == null) {
            return apiResultComponent.error(ApiResultCodeEnum.BOOK_INFO_NULL);
        }
        bookInfo.setBorrowed(true);
        bookInfo.setBorrowUserId(activeUser.getUserId());
        bookInfo.setBorrowedTime(new Date());

        bookInfoService.updateBookInfo(bookInfo);
        bookInfoById = bookInfoService.getBookInfoById(id);
        return apiResultComponent.success(bookInfoById);
    }

    @PostMapping("/revertBook")
    public ApiResult<BookInfo> revertBook(@RequestBody BookInfo bookInfo) {
        Integer id = bookInfo.getId();

        BookInfo bookInfoById = bookInfoService.getBookInfoById(id);
        if (bookInfoById == null) {
            return apiResultComponent.error(ApiResultCodeEnum.BOOK_INFO_NULL);
        }
        bookInfoById.setBorrowed(false);

        bookInfo.setBorrowed(false);
        bookInfoService.updateBookInfo(bookInfo);
        bookInfoById = bookInfoService.getBookInfoById(id);
        return apiResultComponent.success(bookInfoById);
    }

    @PostMapping("/deleteBookInfo")
    public ApiResult<BookInfo> deleteBookInfo(Integer bookInfoId) {
        BookInfo bookInfoById = bookInfoService.getBookInfoById(bookInfoId);
        if (bookInfoById == null) {
            return apiResultComponent.error(ApiResultCodeEnum.BOOK_INFO_NULL);
        }
        bookInfoService.deleteBookInfo(bookInfoId);
        return apiResultComponent.success(bookInfoById);
    }

    @GetMapping("/getBookInfoById")
    public ApiResult<BookInfo> getBookInfoById(Integer id) {
        BookInfo bookInfoById = bookInfoService.getBookInfoById(id);
        if (bookInfoById == null) {
            return apiResultComponent.error(ApiResultCodeEnum.BOOK_INFO_NULL);
        }
        return apiResultComponent.success(bookInfoById);
    }

    @GetMapping("/listTimeoutBookInfo")
    public ApiResult<Pagination<BookInfo>> listTimeoutBookInfo(@SessionAttribute(
        SystemConstant.ACTIVE_USER) ActiveUser activeUser) {

        QueryWarp<BookInfo> queryWarp = new QueryWarp<>();
        queryWarp.put("borrowUserId", activeUser.getUserId());
        queryWarp.put("timeout", true);
        queryWarp.put("sortField", "expected_return_time");
        queryWarp.put("order", "desc");

        PageHelper.startPage(0, 0);
        List<BookInfo> bookInfoList = bookInfoService.listBookInfo(queryWarp);
        return apiResultComponent.success(bookInfoList);
    }

    @GetMapping("/listBookInfo")
    public ApiResult<Pagination<BookInfo>> listBookInfo(BookInfo bookInfo,
        @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
        @RequestParam(value = "pageSize", defaultValue = "0") Integer pageSize,
        @RequestParam(value = "sortField", required = false) String sortField,
        @RequestParam(value = "order", required = false) String order) {

        QueryWarp<BookInfo> bookInfoQueryWarp = new QueryWarp<>();
        bookInfoQueryWarp.put(bookInfo);

        if (StringUtils.isNotEmpty(sortField) && StringUtils.isNotEmpty(order)) {
            bookInfoQueryWarp.put("sortField", sortField);
            bookInfoQueryWarp.put("order", order);
        }

        PageHelper.startPage(pageNum, pageSize);
        List<BookInfo> bookInfoList = bookInfoService.listBookInfo(bookInfoQueryWarp);
        return apiResultComponent.success(bookInfoList);
    }
}
